﻿using System.Linq.Expressions;
using System.Web.Routing;
using TSharp.Core.Mvc.Extensions;

namespace System.Web.Mvc
{
    /// <summary>
    ///     控制器转向强类型扩展
    ///     <para>2010/8/13</para>
    ///     <para>TANGJINGBO</para>
    ///     <para>tangjingbo</para>
    /// </summary>
    public static class ControllerRedirectToActionExtensions
    {
        /// <summary>
        ///     Redirects to action.
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this TController controller,
                                                                           Expression<Action<TController>> action)
            where TController : IController
        {
            return RedirectToActionInternal(action, null);
        }

        /// <summary>
        ///     Redirects to action.
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this IController controller,
                                                                           Expression<Action<TController>> action)
            where TController : IController
        {
            return RedirectToActionInternal(action, null);
        }

        /// <summary>
        ///     Redirects to action.
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this TController controller,
                                                                           Expression<Action<TController>> action,
                                                                           object values)
            where TController : IController
        {
            return RedirectToActionInternal(action, new RouteValueDictionary(values));
        }

        /// <summary>
        ///     Redirects to action.
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this IController controller,
                                                                           Expression<Action<TController>> action,
                                                                           object values)
            where TController : IController
        {
            return RedirectToActionInternal(action, new RouteValueDictionary(values));
        }

        /// <summary>
        ///     Redirects to action.
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this TController controller,
                                                                           Expression<Action<TController>> action,
                                                                           RouteValueDictionary values)
            where TController : IController
        {
            return RedirectToActionInternal(action, values);
        }

        /// <summary>
        ///     重定向
        /// </summary>
        /// <typeparam name="TController">The type of the controller.</typeparam>
        /// <param name="controller">The controller.</param>
        /// <param name="action">The action.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static RedirectToRouteResult RedirectToActionT<TController>(this IController controller,
                                                                           Expression<Action<TController>> action,
                                                                           RouteValueDictionary values)
            where TController : IController
        {
            return RedirectToActionInternal(action, values);
        }

        private static RedirectToRouteResult RedirectToActionInternal<TController>(
            Expression<Action<TController>> action, RouteValueDictionary values)
            where TController : IController
        {
            return new RedirectToRouteResult(ExpressionValuesHelper.GetRouteValuesFromExpression(action, values));
        }
    }
}